using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TextBoxControl
{
    public partial class TextBoxControl : TextBox
    {
        private Point m_CursorOffset;
        private bool m_Moving;
        private Cursor m_CurrentCursor;
        private bool m_StayWithinParent;
        private const string EVENT_STAYWITHINPARENTBOUNDSCHANGED = "StayWithinParentBoundsEvent";
        
        public TextBoxControl()
        {
            InitializeComponent();

            base.MouseDown += new System.Windows.Forms.MouseEventHandler(TextBoxControl_MouseDown);
            base.MouseMove += new System.Windows.Forms.MouseEventHandler(TextBoxControl_MouseMove);
            base.MouseUp += new System.Windows.Forms.MouseEventHandler(TextBoxControl_MouseUp);
            this.Cursor = Cursors.Hand;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: Add custom paint code here

            // Calling the base class OnPaint
            base.OnPaint(pe);
        }

        [Bindable(true), DefaultValue(true), Category("Behavior"), Description("Para que se quede o no dentro de la region visible cuando se mueva"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public bool StayWithinParentBounds
        {
            get
            {
                return m_StayWithinParent;
            }

            set
            {
                if (value != m_StayWithinParent)
                {
                    m_StayWithinParent = value;
                    MoveControlWithinBounds();
                    this.OnStayWithinParentBoundsChanged(EventArgs.Empty);
                }
            }
        }

        protected virtual void OnStayWithinParentBoundsChanged(EventArgs e)
        {
            EventHandler newHandler = base.Events[EVENT_STAYWITHINPARENTBOUNDSCHANGED] as EventHandler;
            if (newHandler != null)
            {
                newHandler.Invoke(this, e);
            }
        }

        private void MovableTexBox_ParentChanged(object sender, System.EventArgs e)
        {
            try
            {
                this.Parent.Resize += new System.EventHandler(Parent_Resize);
            }
            catch (NullReferenceException)
            {
            }
        }

        private void Parent_Resize(object sender, System.EventArgs e)
        {
            if (StayWithinParentBounds)
            {
                MoveControlWithinBounds();
            }
        }

        private void MoveControlWithinBounds()
        {
            if (base.IsHandleCreated)
            {
                MoveControlWithinBounds(new Point(base.Location.X, base.Location.Y));
            }
        }

        private void MoveControlWithinBounds(Point location)
        {
            if (base.IsHandleCreated)
            {
                int x = location.X;
                int y = location.Y;

                if (x > base.Parent.ClientRectangle.Right - base.Width)
                {
                    x = base.Parent.ClientRectangle.Right - base.Width;
                }

                if (y > base.Parent.ClientRectangle.Bottom - base.Height)
                {
                    y = base.Parent.ClientRectangle.Bottom - base.Height;
                }

                if (x < base.Parent.ClientRectangle.Left)
                {
                    x = base.Parent.ClientRectangle.Left;
                }

                if (y < base.Parent.ClientRectangle.Top)
                {
                    y = base.Parent.ClientRectangle.Top;
                }
                base.Location = new Point(x, y);
            }
        }

        private void TextBoxControl_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                m_CursorOffset = e.Location;
                m_CurrentCursor = base.Cursor;
                base.Cursor = Cursors.SizeAll;
                m_Moving = true;
            }
        }

        private void TextBoxControl_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (m_Moving)
            {
                Point clientPosition = base.Parent.PointToClient(System.Windows.Forms.Cursor.Position);
                Point adjustedLocation = new Point(clientPosition.X - m_CursorOffset.X, clientPosition.Y - m_CursorOffset.Y);

                if (StayWithinParentBounds)
                {
                    MoveControlWithinBounds(adjustedLocation);
                }
                else
                {
                    base.Location = adjustedLocation;
                }
            }
        }

        private void TextBoxControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            m_Moving = false;
            base.Cursor = m_CurrentCursor;
        }

    }
}
